// Subcircuits for use in the AMI06 technology
simulator lang=spectre

subckt ccbuffer Vdd Vss in out
parameters wp=3u wn=1.5u ln=600n lp=600n mult=1
	I0 (Vdd Vss in temp) ccInverter
	I1 (Vdd Vss temp bufferout) ccInverter
ends ccbuffer

subckt ccInverter VDD VSS in out 
parameters wp=3u wn=1.5u ln=600n lp=600n mult=1
    MP (out in VDD VDD) ami06P w=wp l=lp as=1.5u*wp ad=1.5u*wp ps=3u+wp \
        pd=3u+wp m=mult 
    MN (out in VSS VSS) ami06N w=wn l=ln as=1.5u*wn ad=1.5u*wn ps=3u+wn \
        pd=3u+wn m=mult
ends ccInverter

subckt adder16bit a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 \
 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15 carryIn0 s0 s1 s2 \
 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 carryOut15 VDD VSS
 	add0 (a0 a1 a2 a3 a4 a5 a6 a7 b0 b1 b2 b3 b4 b5 b6 b7 \
 	carryIn0 s0 s1 s2 s3 s4 s5 s6 s7 carry VDD VSS) MIRRORADDER_8BIT
 	add1 (a8 a9 a10 a11 a12 a13 a14 a15 b8 b9 b10 b11 b12 b13 b14 b15 \
 	carry s8 s9 s10 s11 s12 s13 s14 s15 carryOut15 VDD VSS) MIRRORADDER_8BIT
ends adder16bit

//implement 8-bit adder using mirror adder
subckt MIRRORADDER_8BIT a0 a1 a2 a3 a4 a5 a6 a7 b0 b1 b2 b3 b4 b5 b6 b7 \
carryIn0 s0 s1 s2 s3 s4 s5 s6 s7 carryOut7 vDD vSS
	mA0 (a0 b0 vSS sNOT0 cOutNOT0 vDD vSS) MIRRORADDER widthMult=9.137
	s0Inverter (vDD vSS sNOT0 s0) bcInverter
	a1Inverter (vDD vSS a1 aNOT1) bcInverter
	b1Inverter (vDD vSS b1 bNOT1) bcInverter 
	mA1 (aNOT1 bNOT1 cOutNOT0 s1 cOut1 vDD vSS) MIRRORADDER widthMult=6.421
	mA2 (a2 b2 cOut1 sNOT2 cOutNOT2 vDD vSS) MIRRORADDER widthMult=5.333
	s2Inverter (vDD vSS sNOT2 s2) bcInverter
	a3Inverter (vDD vSS a3 aNOT3) bcInverter
	b3Inverter (vDD vSS b3 bNOT3) bcInverter 
	mA3 (aNOT3 bNOT3 cOutNOT2 s3 cOut3 vDD vSS) MIRRORADDER widthMult=4.430
	mA4 (a4 b4 cOut3 sNOT4 cOutNOT4 vDD vSS) MIRRORADDER widthMult=3.679
	s4Inverter (vDD vSS sNOT4 s4) bcInverter
	a5Inverter (vDD vSS a5 aNOT5) bcInverter
	b5Inverter (vDD vSS b5 bNOT5) bcInverter 
	mA5 (aNOT5 bNOT5 cOutNOT4 s5 cOut5 vDD vSS) MIRRORADDER widthMult=3.056
	mA6 (a6 b6 cOut5 sNOT6 cOutNOT6 vDD vSS) MIRRORADDER widthMult=2.538
	s6Inverter (vDD vSS sNOT6 s6) bcInverter
	a7Inverter (vDD vSS a7 aNOT7) bcInverter
	b7Inverter (vDD vSS b7 bNOT7) bcInverter 
	mA7 (aNOT7 bNOT7 cOutNOT6 s7 cOut7 vDD vSS) MIRRORADDER widthMult=2.108
ends MIRRORADDER_8BIT

//implement full adder on page 567 of book (Figure 11-6)
subckt MIRRORADDER inA inB carryIn invertedSum invertedCarryOut vDD vSS
parameters wp=3u wn=1.5u ln=600n lp=600n mult=1 widthMult=1
	pKillAParallel (int1 inA vDD vDD) ami06P w=wp*widthMult l=lp as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat
	pKillBParallel (int1 inB vDD vDD) ami06P w=wp*widthMult l=lp as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat
	pKillCi (invertedCarryOut carryIn int1 vDD) ami06P w=wp*widthMult l=lp  as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat
	pKillBSeries (int2 inB vDD vDD) ami06P w=wp*widthMult l=lp as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat
	pKillASeries (invertedCarryOut inA int2 vDD) ami06P w=wp*widthMult l=lp as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat
	nGenCi (invertedCarryOut carryIn int3 vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
	nGenAParallel (int3 inA vSS vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
	nGenBParallel (int3 inB vSS vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
	nGenASeries (invertedCarryOut inA int4 vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
	nGenBSeries (int4 inB vSS vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
	pAParallel(int5 inA vDD vDD) ami06P w=wp*widthMult l=lp as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat
	pBParallel(int5 inB vDD vDD) ami06P w=wp*widthMult l=lp as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat
	pCiParallel(int5 carryIn vDD vDD) ami06P w=wp*widthMult l=lp as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat
	pInvertedCarryOut(invertedSum invertedCarryOut int5 vDD) ami06P w=wp*widthMult l=lp as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat
	nInvertedCarryOut(invertedSum invertedCarryOut int6 vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
	nAParallel(int6 inA vSS vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
	nBParallel(int6 inB vSS vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
	nCiParallel(int6 carryIn vSS vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
	pASeries(int7 inA vDD vDD) ami06P w=wp*widthMult l=lp as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat
	pBSeries(int8 inB int7 vDD) ami06P w=wp*widthMult l=lp as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat
	pCiSeries(invertedSum carryIn int8 vDD) ami06P w=wp*widthMult l=lp as=1.5u*wp*widthMult ad=1.5u*wp*widthMult ps=3u+wp*widthMult pd=3u+wp*widthMult m=mult region=sat		
	nCiSeries(invertedSum carryIn int9 vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
	nASeries(int9 inA int10 vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
	nBSeries(int10 inB vSS vSS) ami06N w=wn*widthMult l=ln as=1.5u*wn*widthMult ad=1.5u*wn*widthMult ps=3u+wn*widthMult pd=3u+wn*widthMult m=mult region=sat
ends MIRRORADDER

//I used this inverter for the inverters in my 8-bit adder
// Cell name: bcInverter
// 	      An inverter with sizing parameters and parameterized AD,AS,PD,PS
//	      The S/D parameters assume a single-finger device
subckt bcInverter VDD VSS in out 
parameters wp=3u wn=1.5u ln=600n lp=600n mult=1
    MP (out in VDD VDD) ami06P w=wp l=lp as=1.5u*wp ad=1.5u*wp ps=3u+wp \
        pd=3u+wp m=mult 
    MN (out in VSS VSS) ami06N w=wn l=ln as=1.5u*wn ad=1.5u*wn ps=3u+wn \
        pd=3u+wn m=mult
ends bcInverter

subckt buffer VDD VSS in out
	invA (VDD VSS in out1) bcInverter
	invB (VDD VSS out1 out) bcInverter
ends buffer

subckt fanoutinverter VDD VSS in out
	parameters wp=12u wn=6u ln=600n lp=600n mult=1
    MP (out in VDD VDD) ami06P w=wp l=lp as=1.5u*wp ad=1.5u*wp ps=3u+wp \
        pd=3u+wp m=mult 
    MN (out in VSS VSS) ami06N w=wn l=ln as=1.5u*wn ad=1.5u*wn ps=3u+wn \
        pd=3u+wn m=mult
ends fanoutinverter
// End of subcircuit definition.
